The Gameboard SDK allows developers to track engagement via play events and sessions with the Engagement Controller. Implementing these features will allow us to measure engagement with your game.

To send Play Events from a game running in Godot you want to use the EngagmentController from the Godot SDK.

You can obtain a reference to the EngagementController from our Gameboard Node. This is the controller that handles all the functions related to engagement metrics.

We will first need to define a reference to the controller to make it available throughout our script.

    EngagementController engagementController;
    UserPresenceController userPresenceController;

And then get the controller from the Gameboard node and subscribe to the OnEngagementEvent. This event fires any time you send an engagement event from the EngagementController. In our case we will have a function called OnEngagementEventSent to handle the engagement events.

    var gameboard = GetNode("/root/GameboardSDK") as GameboardPlugin;

    engagementController = gameboard.GetNode("EngagementController") as EngagementController;
    userPresenceController = gameboard.GetNode("UserPresenceController") as UserPresenceController;

    engagementController.OnEngagementEvent += OnEngagementEventSent;

The game session started/ended events are used to provide Gameboard a bit more information about the game. In this case the duration of a given game sessions. How a sessions is defined is up to the game itself but it is important to return the length of that session.

Call SendGameSessionStarted from the Engagement Controller to send a GAME_SESSION_STARTED event. The method takes a list of userIds for the users involved in the game session.

  engagementController.SendGameSessionStarted(new List<string>(userPresenceController.Users.Keys));

Call SendGameSessionEnded to send a GAME_SESSION_ENDED event. This method also takes a list of userIds for the users involved in the game session.

  engagementController.SendGameSessionEnded(new List<string>(userPresenceController.Users.Keys));

You can also use SendUserIdsInSession to send updated users if they change during a game session.

    engagementController.SendUserIdsInSession(new List<string>(userPresenceController.Users.Keys));

Best practices

Game sessions are meant to encapsulate the duration a game is played, not just when the game application is open. So you want to start your game session when the game starts (not in the main menu or lobby), and to end your game session when the game is completed or quit out of (e.g. the user quitting out to the lobby should end the game session).

You can use SendRankingReport to send a ranking report of a game. The game could be in progress or finished based on the type passed.

You can pass the following report types when creating a ranking report:

Below you can see examples for what it would look like to report rankings for these scenarios.

We will assume that a rankingEntries list has been defined in your class, and a currentReportId to update at the start of each game. We can also assume firstTeamMembers and secondTeamMemebers are lists of userIds for each team.

List<RankingEntry> rankingEntries = new List<RankingEntry>();
System.Guid currentReportId;

Reporting the start of the game session

First, you can send a report of the start of the game. Here you can send the starting teams and their default score.

int defaultScore = 0;
rankingEntries.Add(new RankingEntry(firstTeamMembers, 1, defaultScore));
rankingEntries.Add(new RankingEntry(secondTeamMemebers, 1, defaultScore));

// Include a set reportId so all of the rounds will be correlated to the same session.
currentReportId = System.Guid.NewGuid();

RankingReport gameStartReport = new RankingReport(rankingEntries, RankingReportType.GameStarted, reportId: currentReportId);

RankingReportMetric rankingReportMetric = new RankingReportMetric(gameStartReport);

engagementController.SendRankingReport(rankingReportMetric);

Reporting round progress

Now, the first round is complete and the first team is in 1st place now with 500 points, and the second team is in second with 250 points.

// First we will need to clear out the list to remove any previous entries for the start of the game / previous rounds
rankingEntries.Clear();

rankingEntries.Add(new RankingEntry(firstTeamMembers, 1, 500));
rankingEntries.Add(new RankingEntry(secondTeamMemebers, 2, 250));

RankingReport round1Report = new RankingReport(rankingEntries, RankingReportType.RoundEnd, currentRound: 1, reportId: currentReportId);

RankingReportMetric rankingReportMetric = new RankingReportMetric(round1Report);

engagementController.SendRankingReport(rankingReportMetric);

Reporting game finished

If the game ended early and players decided to quit the game then RankingReportType.GameCancelled should be used. Otherwise, if the came was completed with a winner you can use RankingReportType.GameFinished

For the sake of the example, we will say that our game only had 1 round and the first team came out on top, so we will report that our game finished with the same rankingEntries from the last round.

RankingReport gameFinishedReport = new RankingReport(rankingEntries, RankingReportType.GameFinished, currentRound: 1, reportId: currentReportId);

RankingReportMetric rankingReportMetric = new RankingReportMetric(gameFinishedReport);

engagementController.SendRankingReport(rankingReportMetric);

Although we are working in a managed environment it is always a good idea to clean the listeners when no longer needed.

    public override void _ExitTree()
    {
        engagementController.OnEngagementEvent -= OnEngagementEventSent;
    }

This section include the entire code in one single, easy to copy section.

    EngagementController engagementController;
    UserPresenceController userPresenceController;

    //Ranking properties
    List<RankingEntry> rankingEntries = new List<RankingEntry>();
    System.Guid currentReportId;

    //Mock data
    List<string> firstTeamMembers = new List<string>() {"12345", "67890"};
    List<string> secondTeamMemebers = new List<string>() {"420", "1337"}

    // Called when the node enters the scene tree for the first time.
    public override void _Ready()
    {
        gameboard = GetNode("/root/GameboardSDK") as GameboardPlugin;

        engagementController = gameboard.GetNode("EngagementController") as EngagementController;
        userPresenceController = gameboard.GetNode("UserPresenceController") as UserPresenceController;

        engagementController.OnEngagementEvent += OnEngagementEventSent;
    }

    public override void _ExitTree()
    {
        engagementController.OnEngagementEvent -= OnEngagementEventSent;
    }

    public void TestGameSessionStarted()
    {
        engagementController.SendGameSessionStarted(new List<string>(userPresenceController.Users.Keys));

        // --- Ranking start session data ---

        int defaultScore = 0;
        rankingEntries.Add(new RankingEntry(firstTeamMembers, 1, defaultScore));
        rankingEntries.Add(new RankingEntry(secondTeamMemebers, 1, defaultScore));

        // Include a set reportId so all of the rounds will be correlated to the same session.
        currentReportId = System.Guid.NewGuid();

        RankingReport gameStartReport = new RankingReport(rankingEntries, RankingReportType.GameStarted, reportId: currentReportId);

        RankingReportMetric rankingReportMetric = new RankingReportMetric(gameStartReport);

        engagementController.SendRankingReport(rankingReportMetric);
    }

    public void GameSessionEnded()
    {
        engagementController.SendGameSessionEnded(new List<string>(userPresenceController.Users.Keys));

        // --- Ranking end session data ---

        RankingReport gameFinishedReport = new RankingReport(rankingEntries, RankingReportType.GameFinished, currentRound: 1, reportId: currentReportId);

        RankingReportMetric rankingReportMetric = new RankingReportMetric(gameFinishedReport);

        engagementController.SendRankingReport(rankingReportMetric);
    }

    public void UserIdsInSession()
    {
        engagementController.SendUserIdsInSession(new List<string>(userPresenceController.Users.Keys));
    }

    public void SendRankingRoundReport()
    {
        // First we will need to clear out the list to remove any previous entries for the start of the game / previous rounds
        rankingEntries.Clear();

        rankingEntries.Add(new RankingEntry(firstTeamMembers, 1, 500));
        rankingEntries.Add(new RankingEntry(secondTeamMemebers, 2, 250));

        RankingReport round1Report = new RankingReport(rankingEntries, RankingReportType.RoundEnd, currentRound: 1, reportId: currentReportId);

        RankingReportMetric rankingReportMetric = new RankingReportMetric(round1Report);

        engagementController.SendRankingReport(rankingReportMetric);
    }

    public void OnEngagementEventSent(string metricType, string extras)
    {
        // Listen for when engagment events send, for things like checking the sent extras look correct
    }

The following events will be tracked by Gameboard about your game without any effort from you as a Creator: